/* Peter Banda, Daniel Cristofani, Dominic Tippabattuni                     */
/* 975530978    971012079          958842138                                */
/* VMM_Sim Implementation (assignment 5)                                    */
/* CS 538, Portland State University, Fall 2010                             */
/* Turned in November 18, 2010                                              */

/* vmm.h is a header containing definitions used by more than one module.   */

// standard C libraries
#include <stdio.h>		// Input/output.
#include <stdlib.h>		// For exit() and malloc().
#include <limits.h>		// To know the range of different variable types.
#include <stdarg.h>		// Allows varying numbers of arguments for error() and warning().

// replacement of standard bool <stdbool.h> in order to run this on Solaris machines.
#define bool char
#define true 1
#define false 0

#define NO_PD_ENTRIES 1024 // Number of entries in the page directory
#define NO_PT_ENTRIES 1024 // Number of entries in each page table
#define VERSION_INFO "1.0" // First release version
#define CYCLES_FOR_MEMORY_ACCESS 20 // How long a memory access takes
#define CYCLES_FOR_MASS_STORAGE_ACCESS 50000 // How long a disk access takes
#define ACCESS_CLEAR_PERIOD 20 // How often we clear the "accessed" bits
#define DEFAULT_PAGE_FRAME_COUNT 10 // How many page frames by default?
#define DEBUG 0 // Should we print little messages used for debugging? (Not used)

// global variables
int noOfPageFrames; // number of page frames allocated for the simulated program
bool lFlag, tFlag;  // whether the -l debug command and -t trace command are set

// An entry in a page table, with status info about a user page
struct UserPageInfo {
    unsigned int existsBit:1;  // this user page exists, in RAM or on disk.
    unsigned int dirtyBit:1;   // this user page is dirty.
    unsigned int accessedBit:1;// this user page has been accessed recently.
    unsigned int presentBit:1; // this user page is resident in RAM.
};

// An entry in a page directory, with status info about a page table
struct PageTableInfo {
    unsigned int existsBit:1;       // this page table exists, in RAM or on disk.
    unsigned int presentBit:1;      // this page table is resident in RAM.
    unsigned int accessedBit:1;     // this page table has been accessed recently.
    struct UserPageInfo *pageTable; // address of the actual page table
};

// enum type to record different types of commands
enum TypeOfAccess { r, w, l, t, v, p };

// a record of a command that has been processed, for the -t trace command
struct CommandLogEntry {
    unsigned long address;
    enum TypeOfAccess access;
    struct CommandLogEntry *next;
};

// format for the central repository of global statistics about the VMM.
struct Stats { // some of these are self-explanatory.
    unsigned long reads; 
    unsigned long writes;
    unsigned long swapIns;
    unsigned long swapOuts;
    unsigned long replacements; // number of times a non-dirty page was discarded
    unsigned long existingPageTableCount;
    unsigned long existingUserPageCount;
    unsigned long residentPageTableMax;
    unsigned long residentPageTableCount;
    unsigned long residentUserPageMax;
    unsigned long residentUserPageCount;
};

// MAIN MODULE FUNCTIONS

// gives error messages, in printf format, and exits
void error(char *string, ...);
// gives warning messages, in printf format
void warning(char *string, ...);
// gives debug messages if DEBUG !=0
void debug(char *string, ...);

// INPUTHANDLER FUNCTION

//processes all input commands and calls other functions as needed
void inputHandler(void);

// VMM MODULE FUNCTIONS

// simulates a read from virtual memory
void read(unsigned long vAddress);
// simulates a write to virtual memory
void write(unsigned long vAddress);
//  Prints overall VMM state, for the -l command
void printOverallVmmState();

// HISTORYCOLLECTOR FUNCTIONS

// increments the reads counter.
void recordRead();
// increments the writes counter.
void recordWrite();
// increments swaps in counter.
void recordSwapIn();
// records swap in.
void recordSwapOut();
// records replacement.
void recordReplacement();
//  increments existingPageTableCount counter.
void recordPTExists();
//  increments existingUserPageCount counter.
void recordUPExists();
// increments residentPageTableCount counter. Set residentPageTableMax if actual value exceeds it.
void recordPTResident();
// increments residentUserPageCount counter. Set  residentUserPageMax if actual value exceeds it.
void recordUPResident();
//  decrements residentPageTableCount counter.
void recordPTNonResident();
//  decrements residentUserPageCount counter.
void recordUPNonResident();
// records cleared resident pages.
void recordClearedResidentPage();
// adds an item to the tail of the CommandLog, recording a command that was executed.
void addToCommandLog(enum TypeOfAccess accessType, unsigned long address);
// returns Stats containing all global access statistics to be used by StatsPrinter.
struct Stats getStats();
// returns a pointer to CommandLog to be used by StatsPrinter for the -t command.
struct CommandLogEntry *getCommandLog();
// returns the count of reads+writes so far
unsigned long getTotalAccesses(void);

// STATSPRINTER FUNCTIONS

// print the statistics we've gathered, at the end of a run
void printVMMStatistics(void);
// print the version of this program, for the -v command
void printVersionInfo(void);
// print the history of all commands, for the -t command
void printTraceInfo(void);


